<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Transparency</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Java, Java 2D, tutorial, transparency, programming, GUI, multiplatform">
<meta name="description" content="In this part of the Java 2D we work with transparency.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>


<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">

<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Transparency</h1>


<p>
In this part of the Java 2D , we will talk about transparency. 
We will provide some basic definitions and
several interesting transparency effects.
</p>

<div class="center">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* top_horizontal */
google_ad_slot = "3327173442";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<h2>Transparency explained</h2>

<p>
Transparency is the quality of being able to see through a material. 
The easiest way to understand transparency is to imagine a piece of 
glass or water. Technically, the rays of light can go through the glass 
and this way we can see objects behind the glass. 
</p>

<p>
In computer graphics, we can achieve transparency effects using <b>alpha compositing</b>.
Alpha compositing is the process of combining an image with a background 
to create the appearance of partial transparency. 

The composition process uses an <b>alpha channel</b>.
Alpha channel is an 8-bit layer in a graphics file format that is used 
for expressing translucency (transparency). The extra eight bits per pixel 
serves as a mask and represents 256 levels of translucency. 
<br>(answers.com, wikipedia.org)
</p>

<p>
The <code>AlphaComposite</code> class is used to work with 
transparency in Java 2D. It implements the basic alpha compositing 
rules for combining source and destination pixels to achieve blending 
and transparency effects with graphics and images. To create an 
<code>AlphaComposite</code>, you provide two values. The rule 
designator and the alpha value. The rule specifies how we combine source 
and destination pixels. Most often it is AlphaComposite.SRC_OVER. 
The alpha value can range from 0.0f (completely transparent) to 1.0f 
(completely opaque).
</p>



<h2>Transparent rectangles</h2>


<p>
The first example will draw ten rectangles with different levels of transparency. 
</p>

<div class="codehead">TransparentRectangles.java</div>
<pre class="code">
package com.zetcode;


import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class TransparentRectangles extends JPanel {


    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D)g;
        g2d.setColor(Color.BLUE);
 

        for (int i = 1; i &lt;= 10; i++) {
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                        i * 0.1f));
            g2d.fillRect(50 * i, 20, 40, 40);
        }
    }
 

    public static void main(String[] args) {

        JFrame frame = new JFrame("Transparent Rectangles");
        frame.add(new TransparentRectangles());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(590, 120);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
</pre>

<p>
In our example we draw 10 blue rectangles with various levels of transparency applied. 
</p>

<pre class="explanation">
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, i * 0.1f));
</pre>

<p>
This is the key line of the example. We use the forementioned AlphaComposite.SRC_OVER rule. 
The alpha value dynamically changes in the for loop.
</p>


<img src="/img/gfx/java2d/transparentrectangles.png" alt="Transparent rectangles">
<div class="figure">Figure: Transparent rectangles</div>


<h2>Fade out demo</h2>

<p>
In the next example, we will fade out an image. The image will gradually get 
more transparent until it is completely invisible.
</p>

<div class="codehead">FadeOut.java</div>
<pre class="code">
package com.zetcode;

import java.awt.AlphaComposite;
import java.awt.Graphics;

import java.awt.Graphics2D;
import java.awt.Image;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class FadeOut extends JPanel implements ActionListener {

    Image castle;
    Timer timer;
    private float alpha = 1f;

    public FadeOut() {
        castle = new ImageIcon("bardejov.jpg").getImage();
        timer = new Timer(20, this);
        timer.start();
    }

    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D) g;

        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                    alpha));
        g2d.drawImage(castle, 10, 10, null);

    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("Fade out");
        frame.add(new FadeOut());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(280, 240);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }


    public void actionPerformed(ActionEvent e) {
        alpha += -0.01f;
        if (alpha &lt;= 0) {
            alpha = 0;
            timer.stop();
        }
        repaint();
    }
}
</pre>

<p>
With the <code>AlphaComposite</code> we gradually fade out the image on the panel. 
The picture comes from Bardejov, a little town in east part of Slovakia. 
</p>

<pre class="explanation">
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
</pre>

<p>
Working with transparency. 
</p>


<pre class="explanation">
alpha += -0.01f;
</pre>

<p>
In the <code>actionPerformed()</code> method we gradually decrease the 
alpha value. Note, that the alpha value must not be negative.
</p>


<h2>Waiting</h2>

<p>
In this example, we use transparency effect to create a waiting demo. 
We will draw 8 lines that will gradually fade out creating an illusion, 
that a line is moving. Such effects are often used to inform users, 
that a lengthy task is going on behind the scenes. An example is streaming 
video over the Internet.
</p>

<div class="codehead">Waiting.java</div>
<pre class="code">
package com.zetcode;


import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

 

public class Waiting extends JPanel implements ActionListener {

    Timer timer;
    int count;

    public Waiting() {

        timer = new Timer(80, this);
        timer.setInitialDelay(190);
        timer.start();
    }


    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D) g;   
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
                            RenderingHints.VALUE_RENDER_QUALITY);

        final double[][] trs = {
            { 0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1.0 },
            { 1.0, 0.0,  0.15, 0.30, 0.5, 0.65, 0.8, 0.9 },
            { 0.9, 1.0,  0.0,  0.15, 0.3, 0.5, 0.65, 0.8 },
            { 0.8, 0.9,  1.0,  0.0,  0.15, 0.3, 0.5, 0.65},
            { 0.65, 0.8, 0.9,  1.0,  0.0,  0.15, 0.3, 0.5 },
            { 0.5, 0.65, 0.8, 0.9, 1.0,  0.0,  0.15, 0.3 },
            { 0.3, 0.5, 0.65, 0.8, 0.9, 1.0,  0.0,  0.15 },
            { 0.15, 0.3, 0.5, 0.65, 0.8, 0.9, 1.0,  0.0, }
        };

        int width, height;
        width = getWidth();
        height = getHeight();

        g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND,
                                      BasicStroke.JOIN_ROUND));
        g2d.translate(width/2, height/2);

        for (int i = 0; i &lt; 8; i++) {
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                        (float)trs[count%8][i]));

            g2d.rotate(Math.PI/4f);
            g2d.drawLine(0, -10, 0, -40);
        }
    }

     public void actionPerformed(ActionEvent e) {
         repaint();
         count++;
     }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Waiting");
        frame.add(new Waiting());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
</pre>


<p>
We draw eight lines with eight different alpha values.
</p>

<pre class="explanation">
final double[][] trs = { ... }
</pre>

<p>
This is a two dimensional array of transparency values used in this demo. 
There are 8 rows, each for one state. Each of the 8 lines will continuosly 
use these values. 
</p>

<pre class="explanation">
g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
</pre>

<p>
We make the lines a bit thicker, so that they are better visible. We draw 
the lines with rounded caps.
</p>

<pre class="explanation">
g2d.rotate(Math.PI/4f);
g2d.drawLine(0, -10, 0, -40);
</pre>

<p>
This code will draw each of the eight lines. 
</p>


<img src="/img/gfx/java2d/waiting.png" alt="Waiting">
<div class="figure">Figure: Waiting</div>


<p>
In this part of the Java 2D tutorial, we have talked about transparency.
</p>


<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified September 7, 2008  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
